package com.peak.spring.boot.builder.web;

import java.text.MessageFormat;
import java.util.Collection;

import org.springframework.data.domain.Page;

import com.peak.spring.boot.api.constant.ErrorMessage;
import com.peak.spring.boot.api.constant.SuccessMessage;
import com.peak.spring.boot.api.web.IdVo;
import com.peak.spring.boot.api.web.JsonList;
import com.peak.spring.boot.api.web.JsonMessage;
import com.peak.spring.boot.api.web.JsonPage;
import com.peak.spring.boot.core.exception.ProjectException;
import com.peak.spring.boot.tools.Converts;
import com.peak.spring.boot.tools.Emptys;

public class JsonBuilder {

	private JsonMessage message;

	private <T extends JsonMessage> JsonBuilder(T message) {
		this.message = message;
	}

	public static JsonBuilder message() {
		return new JsonBuilder(new JsonMessage());
	}

	public static JsonBuilder list() {
		return new JsonBuilder(new JsonList());
	}

	public static JsonBuilder page() {
		return new JsonBuilder(new JsonPage());
	}

	public JsonBuilder success() {
		this.message.setSuccess(true);
		content(SuccessMessage.SUCCESS);
		return this;
	}

	public JsonBuilder fail() {
		this.message.setSuccess(false);
		return this;
	}

	public JsonBuilder convert(Class<? extends IdVo> clazz) {
		this.message.setTargetClass(clazz);
		return this;
	}

	public JsonBuilder content(Object message, Object... args) {
		if (message instanceof ErrorMessage) {
			this.message.setMessage(((ErrorMessage) message).getMessage(args));
		} else if(message instanceof SuccessMessage) {
			this.message.setMessage(((SuccessMessage) message).getMessage(args));
		} else if (message instanceof ProjectException) {
			this.message.setSuccess(false);
			this.message.setMessage(((ProjectException) message).getMessage());
		} else if (message instanceof String) {
			this.message.setMessage(MessageFormat.format(Converts.toString(message), args));
		} else {
			this.message.setMessage(message);
		}
		return this;
	}

	public <T extends Collection<?>> JsonBuilder list(T list) {
		if (this.message instanceof JsonList) {
			if (Emptys.isNotEmpty(list)) {
				((JsonList) this.message).getRows().addAll(list);
				((JsonList) this.message).setTotalCount(list.size());
			}
		}
		return this;
	}
	
	public JsonBuilder page(Page<?> page) {
		if (this.message instanceof JsonPage) {
			JsonPage json = (JsonPage) this.message;
			json.setSuccess(true);
			json.setPageNo(page.getNumber());
			json.setPageSize(page.getSize());
			json.setTotalCount(Converts.toInt(page.getTotalElements()));
			json.setTotalPage(page.getTotalPages());
			if (Emptys.isNotEmpty(page.getContent())) {
				json.getRows().addAll(page.getContent());
			}
		}
		return this;
	}

	@SuppressWarnings("unchecked")
	public <T extends JsonMessage> T build() {
		return (T) this.message;
	}
}
